
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public abstract class VScriptableRenderPass
{
    public RenderPassEvent m_RenderPassEvent;

    public VScriptableRenderPass(RenderPassEvent renderPassEvent)
    {
        m_RenderPassEvent = renderPassEvent;
    }
    public DrawingSettings CreateDrawingSettings(
            List<ShaderTagId> shaderTagIdList,
            ref VRenderingData renderingData,
            SortingCriteria sortingCriteria     )
    {
        if (shaderTagIdList == null || shaderTagIdList.Count == 0)
        {
            Debug.LogWarning("ShaderTagId list is invalid. DrawingSettings is created with default pipeline ShaderTagId");
            return CreateDrawingSettings(new ShaderTagId("VRP_Lit"), ref renderingData, sortingCriteria);
        }

        DrawingSettings settings = CreateDrawingSettings(shaderTagIdList[0], ref renderingData, sortingCriteria);
        for (int i = 1; i < shaderTagIdList.Count; ++i)
            settings.SetShaderPassName(i, shaderTagIdList[i]);
        return settings;
    }

    public DrawingSettings CreateDrawingSettings(
        ShaderTagId shaderTagId, 
        ref VRenderingData renderingData, 
        SortingCriteria sortingCriteria         )
    {
        Camera camera = renderingData.cameraData.camera;
        SortingSettings sortingSettings = new SortingSettings(camera) { criteria = sortingCriteria };
        DrawingSettings settings = new DrawingSettings(shaderTagId, sortingSettings)
        {
        };
        return settings;
    }
    
    public virtual void OnCameraSetup(CommandBuffer cmd, ref VRenderingData renderingData)
    { }
    public virtual void OnCameraCleanup(CommandBuffer cmd)
    {}
    public virtual void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
    { }
    public abstract void Execute(ScriptableRenderContext context, ref VRenderingData renderingData);

    public static bool operator <(VScriptableRenderPass lhs, VScriptableRenderPass rhs)
    {
        return lhs.m_RenderPassEvent < rhs.m_RenderPassEvent;
    }

    public static bool operator >(VScriptableRenderPass lhs, VScriptableRenderPass rhs)
    {
        return lhs.m_RenderPassEvent > rhs.m_RenderPassEvent;
    }
}

public class VDrawSkyboxPass : VScriptableRenderPass
{
    public VDrawSkyboxPass(RenderPassEvent renderPassEvent):base(renderPassEvent)
    {

    }

    public override void Execute(ScriptableRenderContext context, ref VRenderingData renderingData)
    {
        Debug.Log("CustomDrawSkyboxPass Execute");

        context.DrawSkybox(renderingData.cameraData.camera);
    }
}

public class VDrawObjectPass : VScriptableRenderPass
{
    List<ShaderTagId> m_ShaderTagIdList = new List<ShaderTagId>();
    const string k_RenderDrawobjectPassTag = "Render Drawobject Pass";
    private static readonly ProfilingSampler m_ProfilingRenderPass = 
        new ProfilingSampler(k_RenderDrawobjectPassTag);
    public VDrawObjectPass(RenderPassEvent renderPassEvent):base(renderPassEvent)
    {
        m_ShaderTagIdList.Add(new ShaderTagId("VRP_Unlit"));
        m_ShaderTagIdList.Add(new ShaderTagId("VRP_Lit"));
    }

    public override void Execute(ScriptableRenderContext context, ref VRenderingData renderingData)
    {
        
        CommandBuffer cmd = CommandBufferPool.Get();
        
        using (new ProfilingScope(cmd, m_ProfilingRenderPass))
        {
            cmd.ClearRenderTarget(true, true, Color.black, 1);
            
            
        }
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
        var sortingSettings = new SortingSettings(renderingData.cameraData.camera);

        var drawingSettings =
            CreateDrawingSettings(m_ShaderTagIdList, ref renderingData, SortingCriteria.BackToFront);
        
        var filteringSettings = new FilteringSettings(RenderQueueRange.all);

        ScriptableCullingParameters cullingParameters;
        renderingData.cameraData.camera.TryGetCullingParameters(false, out cullingParameters);
        var cullResults = context.Cull(ref cullingParameters);
            
        context.DrawRenderers(
            cullResults, ref drawingSettings, ref filteringSettings
        );
        

    }
}
public class VBlurPass : VScriptableRenderPass
{
    public VBlurPass(RenderPassEvent renderPassEvent):base(renderPassEvent)
    {

    }

    public override void Execute(ScriptableRenderContext context, ref VRenderingData renderingData)
    {
        

        
    }
}